﻿using System;
using System.Collections.Generic;
using System.Linq;
using AMM.CustomClassLibrary;
using AMM.DataAccess.Store;
using AMM.Model;
using AMM.Model.Store;

namespace AMM.Business.Store {
    public class SuspenseOrderProcessor : BaseProcessor {

        private int _pageSize;
        private SuspenseOrderRepository _suspenseOrderRepository;
        private ProcurementOrderRepository _procurementOrderRepository;

        public SuspenseOrderProcessor(int pageSize = int.MaxValue) {
            this._pageSize = pageSize;
            this._suspenseOrderRepository = new SuspenseOrderRepository(pageSize);
            this._procurementOrderRepository = new ProcurementOrderRepository();
        }

        public SuspenseOrder FetchSuspenseOrderById(int suspenseOrderId) {
            try {
                return this._suspenseOrderRepository.FetchSuspenseOrderById(suspenseOrderId);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取指定暂收单失败！");
            }
        }

        public List<SuspenseOrderDetailsViewModel> FetchSuspenseOrderDetailsViewModelList(int suspenseOrderId) {
            try {
                SuspenseOrder so = this.FetchSuspenseOrderById(suspenseOrderId);
                ProcurementOrder po = this._procurementOrderRepository.FetchProcurementOrderById(so.ProcurementOrderId);

                return this._suspenseOrderRepository.FetchSuspenseOrderByIdForView(suspenseOrderId).SuspenseOrderDetails.Select(x => {
                    return new SuspenseOrderDetailsViewModel() {
                        Key = x.SuspenseOrderDetailsId,
                        MaterialCode = x.Material.Code,
                        SuspenseQuantity = x.SuspenseQuantity,
                        SuspenseDate = x.SuspenseDate,
                        CreatedBy = x.CreatedBy,
                        CreatedDatetime = x.CreatedDatetime,
                        ModifiedBy = x.ModifiedBy,
                        ModifiedDatetime = x.ModifiedDatetime,
                        InStoredQuantity = po.ProcurementOrderDetails.FirstOrDefault(y => y.MaterialId == x.MaterialId).InStoreQuantity,
                        SuspensedQuantity = po.ProcurementOrderDetails.FirstOrDefault(y => y.MaterialId == x.MaterialId).SuspenseQuantity,
                        UnQualifiedQuantity = po.ProcurementOrderDetails.FirstOrDefault(y => y.MaterialId == x.MaterialId).UnQualifiedQuantity
                    };
                }).ToList();
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取指定暂收单失败！");
            }
        }

        public List<SuspenseOrderViewModel> FetchSuspenseOrderViewModelList(SuspenseOrderSearchModel searchModel, int pageIndex = 1) {
            try {
                List<SuspenseOrder> resultList = this._suspenseOrderRepository.FetchSuspenseOrderList(searchModel, pageIndex);
                return resultList.Select(x => {
                    return new SuspenseOrderViewModel() {
                        Key = x.SuspenseOrderId,
                        Code = x.Code,
                        DeliveryOrderCode = x.DeliveryOrderCode,
                        ProcurementOrderCode = x.ProcurementOrder.Code,
                        Remarks = x.Remarks,
                        CreatedBy = x.CreatedBy,
                        CreatedDatetime = x.CreatedDatetime,
                        ModifiedBy = x.ModifiedBy,
                        ModifiedDatetime = x.ModifiedDatetime
                    };
                }).ToList();
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取暂收单列表失败！");
            }
        }

        public List<SuspenseOrderDetail> FetchSuspenseOrderDetailList(int procurementOrderId) {
            try {
                return this._suspenseOrderRepository.FetchSuspenseOrderDetailList(procurementOrderId);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取暂收单明细列表失败！");
            }
        }

        public List<SuspenseOrderViewModel> FetchQualifiedSuspenseOrderList() {
            try {
                List<SuspenseOrder> resultList = this._suspenseOrderRepository.FetchQualifiedSuspenseOrderList();
                return resultList.Select(x => {
                    return new SuspenseOrderViewModel() {
                        Key = x.SuspenseOrderId,
                        Code = x.Code,
                        DeliveryOrderCode = x.DeliveryOrderCode,
                        ProcurementOrderCode = x.ProcurementOrder.Code,
                        Remarks = x.Remarks,
                        CreatedBy = x.CreatedBy,
                        CreatedDatetime = x.CreatedDatetime,
                        ModifiedBy = x.ModifiedBy,
                        ModifiedDatetime = x.ModifiedDatetime
                    };
                }).ToList();
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取暂收单列表失败！");
            }
        }

        public void Insert(SuspenseOrder suspenseOrder) {
            try {
                suspenseOrder.SuspenseOrderId = Guid.NewGuid().GetHashCode();
                suspenseOrder.CreatedDatetime = DateTime.Now;
                suspenseOrder.SuspenseOrderDetails.ToList().ForEach(x => {
                    x.CreatedBy = suspenseOrder.CreatedBy;
                    x.CreatedDatetime = suspenseOrder.CreatedDatetime;
                    x.SuspenseOrderDetailsId = Guid.NewGuid().GetHashCode();
                });
                this._suspenseOrderRepository.Insert(suspenseOrder);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("插入新暂收单失败！");
            }
        }

        public void Update(SuspenseOrder suspenseOrder) {
            try {
                SuspenseOrder oldSuspenseOrder = this.FetchSuspenseOrderById(suspenseOrder.SuspenseOrderId);
                if (!oldSuspenseOrder.RowVersion.SequenceEqual(suspenseOrder.RowVersion)) {
                    throw this.BuildException("更新暂收单失败，数据不一致性错误！");
                }
                suspenseOrder.ModifiedDatetime = DateTime.Now;
                this._suspenseOrderRepository.UpdateSuspenseOrder(suspenseOrder);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("更新暂收单失败！");
            }
        }

        public void Delete(SuspenseOrder suspenseOrder) {
            try {
                this._suspenseOrderRepository.Delete(suspenseOrder);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("删除暂收单失败！");
            }
        }

        public void Delete(params int[] suspenseOrderIds) {
            try {
                this._suspenseOrderRepository.DeleteMultipleSuspenseOrder(suspenseOrderIds);
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("删除暂收单失败！");
            }
        }

        public int GetTheMaxFlowNumber(string startString) {
            try {
                return this._suspenseOrderRepository.GetTheMaxFlowNumber(startString) + 1;
            }
            catch (Exception ex) {
                Logger.Error(ex.Message, ex);
                throw this.BuildException("获取暂收单最大流水号失败！");
            }
        }
    }
}
